package cn.wolfcode.luowowo.website.web.controller;

import cn.wolfcode.luowowo.article.domain.Destination;
import cn.wolfcode.luowowo.article.domain.StrategyDetail;
import cn.wolfcode.luowowo.article.query.DestinationQuery;
import cn.wolfcode.luowowo.article.service.IDestinationService;
import cn.wolfcode.luowowo.article.service.IStrategyDetailService;
import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.comment.domain.HotelComment;
import cn.wolfcode.luowowo.comment.service.IHotelCommentService;
import cn.wolfcode.luowowo.hotel.domain.Hotel;
import cn.wolfcode.luowowo.hotel.domain.HotelRoomType;
import cn.wolfcode.luowowo.hotel.domain.HotelTheme;
import cn.wolfcode.luowowo.hotel.domain.HotelThemeCity;
import cn.wolfcode.luowowo.hotel.query.HotelQueryObject;
import cn.wolfcode.luowowo.hotel.service.*;
import cn.wolfcode.luowowo.hotel.vo.HotelOrderVo;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.search.query.HotelSearchQueryObject;
import cn.wolfcode.luowowo.search.service.HotelTemplateSearchService;
import cn.wolfcode.luowowo.search.template.HotelTemplate;
import cn.wolfcode.luowowo.util.AjaxResult;
import cn.wolfcode.luowowo.website.annotation.UserParam;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.catalina.User;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 酒店控制器
 *
 * @author win
 */
@Controller
@RequestMapping("hotel")
public class HotelController {

    @Reference
    private IHotelService hotelService;

    @Reference
    private IDestinationService destinationService;

    @Reference
    private IHotelThemeService hotelThemeService;

    @Reference
    private IStrategyDetailService strategyDetailService;

    @Reference
    private IHotelThemeCityService hotelThemeCityService;

    @Reference
    private IHotelRoomTypeService hotelRoomTypeService;

    @Reference
    private IHotelOrderService hotelOrderService;

    @Reference
    private HotelTemplateSearchService hotelTemplateSearchService;

    @Reference
    private IHotelCommentService hotelCommentService;

    @Reference
    private IUserInfoRedisService userInfoRedisService;

    @RequestMapping("")
    public String index(Model model) {
        // dest 国内
        // overseas 海外
        List<Destination> dest = destinationService.queryDestByParent(1L);
        List<Destination> overseas = destinationService.queryOverseas();
        model.addAttribute("dest", dest);
        model.addAttribute("overseas", overseas);
        // hotelTags 酒店主题
        List<HotelTheme> themes = hotelThemeService.selectAll();
        model.addAttribute("hotelTags", themes);
        // 特价酒店 hotelCity
        model.addAttribute("hotelCity", dest);
        return "hotel/hotel";
    }

    /**
     * @param qo
     * @return
     */
    @RequestMapping("{destId:\\d*}")
    public String hotelDetail(@ModelAttribute("qo") HotelQueryObject qo, Model model) {
        getDestination(qo, model);
        List<StrategyDetail> details = strategyDetailService.queryDetailTop3(qo.getDestId());
        if (details != null && details.size() > 0) {
            StrategyDetail detail = details.get(0);
            model.addAttribute("strategy", detail);
        }
        return "hotel/tx";
    }

    @RequestMapping("/h")
    public String h(@ModelAttribute("qo") HotelQueryObject qo, Model model) {
        Destination destination = getDestination(qo, model);
        // 根据目的地的编号查询攻略
        List<StrategyDetail> details = strategyDetailService.queryDetailTop3(destination.getId());
        if (details != null && details.size() > 0) {
            StrategyDetail detail = details.get(0);
            model.addAttribute("strategy", detail);
        }
        return "hotel/tx";
    }

    private Destination getDestination(HotelQueryObject qo, Model model) {
        List<HotelTemplate> hotels;
        if (qo.getDestId() == -1) {
            hotels = hotelTemplateSearchService.queryByHotelDestName(qo.getName());
        } else {
            hotels = hotelTemplateSearchService.queryByDestinationId(qo.getDestId());
        }
        DestinationQuery destQo = new DestinationQuery();
        destQo.setDestId(qo.getDestId());
        destQo.setName(qo.getName());
        Destination destination = destinationService.getDestinationIdOrName(destQo);
        if (destination != null) {
            qo.setDestId(destination.getId());
            qo.setName(destination.getName());
        }
        Destination country = destinationService.getCountry(qo.getDestId());
        model.addAttribute("country", country);
        List<HotelTheme> themes = hotelThemeService.selectAll();
        model.addAttribute("themes", themes);
        // 查询关联区域
        List<Destination> destinations = destinationService.queryRelatedDest(destQo);
        model.addAttribute("hotels", hotels);
        model.addAttribute("destinations", destinations);
        return destination;
    }

    /**
     * 根据主题查询酒店
     *
     * @return
     */
    @RequestMapping("/theme")
    public String theme(Long themeId, Model model) {
        List<HotelThemeCity> themeCities = hotelThemeCityService.queryTop6ByThemeId(themeId);
        for (HotelThemeCity themeCity : themeCities) {
            // 设置主题城市所在的国家
            themeCity.getCity().setParent(destinationService.getCountry(themeCity.getCity().getId()));
        }
        model.addAttribute("list", themeCities);
        return "hotel/hotelTpl";
    }

    @RequestMapping("/theme1")
    public String queryByCityId(Long cityId, Model model) {
        List<HotelTemplate> hotelTemplates = hotelTemplateSearchService.queryByDestIdTop8InScore(cityId);
        model.addAttribute("list", hotelTemplates);
        return "hotel/hotelTpl1";
    }

    @RequestMapping("/hotelInfo/{hotelId}")
    public String hotelInfo(@ModelAttribute("qo") HotelQueryObject qo, Model model, @UserParam UserInfo userInfo) {
        addHotelOrderDataToModel(qo, model);
        if (userInfo != null && userInfo.getId() != null) {
            model.addAttribute("hotelIds", userInfoRedisService.getHotelIdByUserId(userInfo.getId()));
        }
        return "hotel/hotelInfo";
    }

    @RequestMapping("/hotelOrder/{hotelId}")
    public String hotelOrder(@ModelAttribute("qo") HotelQueryObject qo, Model model, @UserParam UserInfo userInfo) {
        addHotelOrderDataToModel(qo, model);
        // 根据酒店编号查询酒店房间
        List<HotelRoomType> hotelRoomTypes = hotelRoomTypeService.findById(qo.getHotelId());
        Map<String, Object> room = new HashMap<>();
        for (HotelRoomType hotelRoomType : hotelRoomTypes) {
            room.put(hotelRoomType.getType().toString(), hotelRoomType.getPrice());
        }
        if (userInfo != null && userInfo.getId() != null) {
            model.addAttribute("hotelIds", userInfoRedisService.getHotelIdByUserId(userInfo.getId()));
        }
        model.addAttribute("room", room);
        return "hotel/hotelOrder";
    }

    private void addHotelOrderDataToModel(HotelQueryObject qo, Model model) {
        Hotel hotel = hotelService.queryByHotelId(qo);
        if (qo.getCheckIn() == null || qo.getCheckOut() == null) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DAY_OF_MONTH, 1);
            qo.setCheckIn(dateFormat.format(new Date()));
            qo.setCheckOut(dateFormat.format(c.getTime()));
        }
        Map<String, Object> map = hotelService.thereRoom(qo);
        boolean flag = false;
        for (Object value : map.values()) {
            if (!value.equals(0)) {
                flag = true;
            }
        }
        List<HotelComment> comments = hotelCommentService.queryByHotelId(qo.getHotelId());
        long count = hotelCommentService.queryCountByHotelId(qo.getHotelId());
        model.addAttribute("commentNum", count);
        model.addAttribute("comments", comments);
        model.addAttribute("flag", flag);
        Destination country = destinationService.getCountry(hotel.getDest().getId());

        model.addAttribute("country", country);
        model.addAttribute("hotel", hotel);
        model.addAttribute("map", map);
    }

    @RequestMapping("/order")
    @ResponseBody
    public Object order(HotelOrderVo vo, @UserParam UserInfo userInfo) {
        if (userInfo == null) {
            AjaxResult result = new AjaxResult(false, "请登录");
            result.setCode(102);
            return result;
        }
        try {
            boolean flag = hotelOrderService.orderHotel(vo, userInfo);
            if (flag) {
                return new AjaxResult(flag);
            } else {
                AjaxResult result = new AjaxResult(flag);
                result.setCode(201);
                return result;
            }
        } catch (Exception e) {
            return AjaxResult.FAIL;
        }
    }

    @RequestMapping("/search")
    public String search(HotelSearchQueryObject qo, Model model) {
        Page<HotelTemplate> hotelTemplates = hotelTemplateSearchService.searchByQo(qo);
        model.addAttribute("hotelPage", hotelTemplates);
        return "hotel/hotelSimpleInfoTmpl";
    }

    @RequestMapping("/commentAdd")
    public Object addComment(HotelComment hotelComment, Model model, @UserParam UserInfo userInfo) {
        if (userInfo == null) {
            return new AjaxResult(false, "请先登录");
        }
        hotelComment.setUserId(userInfo.getId());
        hotelComment.setUserName(userInfo.getNickname());
        hotelComment.setLevel(userInfo.getLevel());
        hotelComment.setHeadImgUrl(userInfo.getHeadImgUrl());
        hotelComment.setCreateTime(new Date());
        model.addAttribute("hotelComment", hotelCommentService.saveOrUpdate(hotelComment));
        return "hotel/hotelComment";
    }

    /**
     * 酒店收藏
     *
     * @param hotelId  酒店编号
     * @param userInfo 用户编号
     * @return
     */
    @RequestMapping("favorite")
    @ResponseBody
    public Object favoriteOrCancelHotel(Long hotelId, @UserParam UserInfo userInfo) {
        if (userInfo == null) {
            AjaxResult result = new AjaxResult(false, "未登录, 请登录");
            result.setCode(102);
            return result;
        }
        boolean result = userInfoRedisService.favoriteHotel(hotelId, userInfo.getId());
        return new AjaxResult(result);
    }
}
